﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	/// <summary>
	/// 调查项类。
	/// </summary>
	[SerializableAttribute]
	public class VoteItem
	{
		public string OptionTitle { get; set; }
		public int VoteCount { get; set; }
	}



	public partial class Vote : ICreator { }
	public partial class Vote
	{
		private LoadedValue<List<VoteItem>> loadedVoteItemList;
		public List<VoteItem> VoteItemList
		{
			get
			{
				if (loadedVoteItemList.Loader == null)
					loadedVoteItemList.Loader = () => Votes.DeserializeVoteItems(VoteItems);
				return loadedVoteItemList.Value;
			}
			set
			{
				VoteItems = Votes.SerializeVoteItems(value);
				loadedVoteItemList.ResetValue();
			}
		}
	}




	/// <summary>
	/// Votes 类。
	/// </summary>
	public static partial class Votes
	{
		public const string INFO_TYPE = "Vote";



		#region GetItem
		/// <summary>
		/// 根据标识获取指定的调查。
		/// </summary>
		/// <param name="o">调查集合。</param>
		/// <param name="voteId">获取的调查标识 VoteId。</param>
		/// <returns>获取的信息项。</returns>
		public static Vote GetItem(this System.Data.Linq.Table<Vote> o, int voteId)
		{
			return o.SingleOrDefault(p => p.VoteId == voteId);
		}

		/// <summary>
		/// 获取调查项。
		/// </summary>
		/// <param name="voteId">调查项的标识。</param>
		/// <returns>调查项。</returns>
		public static Vote GetItem(int voteId)
		{
			return GetItem(voteId, false);
		}

		/// <summary>
		/// 获取调查项。
		/// </summary>
		/// <param name="voteId">调查项的标识。</param>
		/// <param name="objectTrackingEnabled">跟踪对象。</param>
		/// <returns>调查项。</returns>
		public static Vote GetItem(int voteId, bool objectTrackingEnabled)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = objectTrackingEnabled;
			return dc.Votes.GetItem(voteId);
		}
		#endregion



		#region Exists
		/// <summary>
		/// 验证指定的调查是否已经存在。
		/// </summary>
		/// <param name="o">调查集合。</param>
		/// <param name="voteId">验证的调查标识 VoteId。</param>
		/// <returns>布尔值表示指定的调查是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<Vote> o, int voteId)
		{
			return o.Any(p => p.VoteId == voteId);
		}
		#endregion




		#region SerializeVoteItems
		/// <summary>
		/// 序列化调查项信息。
		/// </summary>
		/// <param name="voteItems">进行序列化的调查项数组。</param>
		/// <returns>序列化的调查项信息。</returns>
		public static string SerializeVoteItems(List<VoteItem> voteItems)
		{
			if (voteItems == null) return "";
			XmlSerializer serializer = new XmlSerializer(typeof(List<VoteItem>));
			StringBuilder content = new StringBuilder();
			XmlWriter writer = XmlWriter.Create(content);
			serializer.Serialize(writer, voteItems);
			return content.ToString();
		}

		/// <summary>
		/// 反序列化调查项信息。
		/// </summary>
		/// <param name="voteItems">进行反序列化的调查项内容。</param>
		/// <returns>反序列化的调查项信息。</returns>
		public static List<VoteItem> DeserializeVoteItems(string voteItems)
		{
			if (string.IsNullOrEmpty(voteItems)) return new List<VoteItem> { };
			XmlSerializer serializer = new XmlSerializer(typeof(List<VoteItem>));
			StringReader reader = new StringReader(voteItems);
			return (List<VoteItem>)serializer.Deserialize(reader);
		}
		#endregion
	}



	/// <summary>
	/// Votes 类操作部分。
	/// </summary>
	public static partial class Votes
	{
		#region Vote
		/// <summary>
		/// 投票。
		/// </summary>
		/// <param name="insertedVoteResult">投票的信息。</param>
		/// <returns>添加的调查结果项。</returns>
		public static VoteResult Vote(VoteResult insertedVoteResult)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Vote vote = dc.Votes.GetItem(insertedVoteResult.VoteId);
			if (vote == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetVoteRight(dc, vote, true);	// 权限验证

			// 更新票数
			if (insertedVoteResult.SelectedIndexs != null && insertedVoteResult.SelectedIndexs.Length > 0)
			{
				var itemList = vote.VoteItemList;
				foreach (int index in insertedVoteResult.SelectedIndexs)
				{
					if (itemList.Count >= index)
					{
						itemList[index - 1].VoteCount += 1;
						vote.VoteCount += 1;
					}
				}
				vote.VoteItemList = itemList;
			}
			if (!string.IsNullOrEmpty(insertedVoteResult.UserDefinedContent))
			{
				vote.UserDefinedCount += 1;
				vote.VoteCount += 1;
			}

			VoteResult voteResult = insertedVoteResult.ToNewEntity<VoteResult>();
			voteResult.VoteDate = DateTime.Now;
			voteResult.UserId = Users.CurrentUserId;

			dc.VoteResults.InsertOnSubmit(voteResult);
			dc.SubmitChanges();

			// 返回只读数据
			return insertedVoteResult.FillByEntity(voteResult);
		}
		#endregion



		#region Insert
		/// <summary>
		/// 添加调查。
		/// </summary>
		/// <param name="insertedVote">添加的调查。</param>
		/// <returns>添加的调查。</returns>
		public static Vote Insert(Vote insertedVote)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Vote vote = insertedVote.ToNewEntity<Vote>();
			vote.CreatorId = Users.CurrentUserId;
			vote.CreationDate = DateTime.Now;
			vote.Order = 0;
			vote.IsEffective = false;

			GetInsertRight(dc, vote, true);	// 权限验证

			dc.Votes.InsertOnSubmit(vote);
			dc.SubmitChanges();

			// 记录日志
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(vote.ClassId);
			Logs.Insert(dc, resourceId, (int)VoteClasses.VoteReleasePermissionCode.Insert, INFO_TYPE, vote.VoteId.ToString(), VoteClasses.VoteReleasePermissionCode.Insert.ToString(), vote.Title);

			// 返回只读数据
			return insertedVote.FillByEntity(vote);
		}
		#endregion



		#region Update
		private static readonly HashSet<string> _updatedExcludeColumns = typeof(Vote).GetEntityColumnNames(new string[] {
				"VoteId",
				"ClassId",
				"VoteCount",
				"IsEffective",
				"Order",
				"CreatorId",
				"CreationDate",
				"IsHomeDisplay"
			}, true);

		/// <summary>
		/// 修改调查。
		/// </summary>
		/// <param name="updatedVote">修改的调查。</param>
		/// <returns>修改的调查。</returns>
		public static Vote Update(Vote updatedVote)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Vote vote = dc.Votes.GetItem(updatedVote.VoteId);
			if (vote == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, vote, true);	// 权限验证

			vote.FillByEntity(updatedVote, EntityColumnsSetType.Exclude, _updatedExcludeColumns);
			ResetVoteCount(vote);

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(vote.ClassId);
			Logs.Insert(dc, resourceId, (int)VoteClasses.VoteReleasePermissionCode.Update, INFO_TYPE, vote.VoteId.ToString(), VoteClasses.VoteReleasePermissionCode.Update.ToString(), vote.Title);

			// 返回只读数据
			return updatedVote.FillByEntity(vote);
		}
		#endregion



		#region Delete
		/// <summary>
		/// 删除调查。
		/// </summary>
		/// <param name="voteId">删除的调查标识 VoteId。</param>
		public static void Delete(int voteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Vote vote = dc.Votes.GetItem(voteId);
			if (vote == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetDeleteRight(dc, vote, true);	// 权限验证

			Delete(dc, vote);

			dc.SubmitChanges();

			// 记录日志
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(vote.ClassId);
			Logs.Insert(dc, resourceId, (int)VoteClasses.VoteReleasePermissionCode.Delete, INFO_TYPE, vote.VoteId.ToString(), VoteClasses.VoteReleasePermissionCode.Delete.ToString(), vote.Title);
		}

		#region internal Delete
		internal static void Delete(GenericModuleDataContext dc, Vote vote)
		{
			VoteResults.DeleteByParent(dc, vote);	// 删除关联数据
			dc.Votes.DeleteOnSubmit(vote);
		}

		internal static void DeleteByParent(GenericModuleDataContext dc, VoteClass parent)
		{
			IEnumerable<Vote> e = parent.Votes.AsEnumerable();
			foreach (Vote i in e)
				Delete(dc, i);
		}
		#endregion
		#endregion



		#region Setting
		private static readonly HashSet<string> _settedColumns = typeof(Vote).GetEntityColumnNames(new string[] {
				"IsEffective",
				"Order",
				"IsHomeDisplay"
			}, true);

		/// <summary>
		/// 设置调查。
		/// </summary>
		/// <param name="settedVote">设置的调查。</param>
		/// <returns>设置的调查。</returns>
		public static Vote Setting(Vote settedVote)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Vote vote = dc.Votes.GetItem(settedVote.VoteId);
			if (vote == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetSettingRight(dc, vote, true);	// 权限验证

			vote.FillByEntity(settedVote, _settedColumns);

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(vote.ClassId);
			Logs.Insert(dc, resourceId, (int)VoteClasses.VoteReleasePermissionCode.Setting, INFO_TYPE, vote.VoteId.ToString(), VoteClasses.VoteReleasePermissionCode.Setting.ToString(), vote.Title);

			// 返回只读数据
			return settedVote.FillByEntity(vote);
		}
		#endregion

		public static void SetHomeDisplay(int voteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Vote vote = dc.Votes.GetItem(voteId);
			if (vote == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetSetEffectiveStateRight(dc, vote, true);	// 权限验证

			vote.IsHomeDisplay = !vote.IsHomeDisplay;
			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(vote.ClassId);
			Logs.Insert(dc, resourceId, (int)VoteClasses.VoteReleasePermissionCode.Setting, INFO_TYPE, vote.VoteId.ToString(), VoteClasses.VoteReleasePermissionCode.Setting.ToString() + "/SetHomeDisplay", vote.Title);
		
		}

		#region SetEffectiveState
		/// <summary>
		/// 设置信息的有效状态。
		/// </summary>
		/// <param name="voteId">设置的信息标识。</param>
		/// <param name="state">设置的状态。</param>
		public static void SetEffectiveState(int voteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Vote vote = dc.Votes.GetItem(voteId);
			if (vote == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetSetEffectiveStateRight(dc, vote, true);	// 权限验证

			vote.IsEffective = !vote.IsEffective;
			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(vote.ClassId);
			Logs.Insert(dc, resourceId, (int)VoteClasses.VoteReleasePermissionCode.Setting, INFO_TYPE, vote.VoteId.ToString(), VoteClasses.VoteReleasePermissionCode.Setting.ToString() + "/EffectiveState", vote.Title);
		}

		/// <summary>
		/// 设置信息的有效状态。
		/// </summary>
		/// <param name="voteId">设置的信息标识。</param>
		/// <param name="state">设置的状态。</param>
		public static void SetEffectiveState(int voteId, bool state)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Vote vote = dc.Votes.GetItem(voteId);
			if (vote == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetSetEffectiveStateRight(dc, vote, true);	// 权限验证

			if (vote.IsEffective == state)
				return;

			vote.IsEffective = state;
			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(vote.ClassId);
			Logs.Insert(dc, resourceId, (int)VoteClasses.VoteReleasePermissionCode.Setting, INFO_TYPE, vote.VoteId.ToString(), VoteClasses.VoteReleasePermissionCode.Setting.ToString() + "/EffectiveState", vote.Title);
		}
		#endregion




		#region ResetVoteCount
		internal static bool ResetVoteCount(GenericModuleDataContext dc, int voteId)
		{
			Vote vote = dc.Votes.GetItem(voteId);
			if (vote == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			ResetVoteCount(vote);

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			return true;
		}

		internal static void ResetVoteCount(Vote vote)
		{
			vote.VoteCount = vote.UserDefinedCount + (from p in vote.VoteItemList select (int?)p.VoteCount).Sum() ?? 0;
		}
		#endregion
	}



	/// <summary>
	/// Votes 类对应操作权限部分。（受限站点资源。）
	/// </summary>
	public static partial class Votes
	{
		#region GetInsertRight
		/// <summary>
		/// 获取当前用户是否有添加调查的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="vote">添加的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加调查的权限。</returns>
		public static bool GetInsertRight(GenericModuleDataContext dc, Vote vote, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)VoteClasses.VoteReleasePermissionCode.Insert;
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(dc.VoteClasses.GetItem(vote.ClassId));
			if (!resourceId.HasValue)
				throw new ObjectNotExistsException(Res.Resources_NotExistsResource);

			bool b = dc.AccessController.GetUserIsHasPermission<Vote>(userName, vote, resourceId.Value, permissionCode);

			if (triggerException && !b)
				throw new PermissionException(userName, vote, resourceId.Value, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有添加调查的权限。
		/// </summary>
		/// <param name="vote">添加的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加调查的权限。</returns>
		public static bool GetInsertRight(Vote vote, bool triggerException)
		{
			return GetInsertRight(new GenericModuleDataContext(), vote, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有添加调查的权限。
		/// </summary>
		/// <param name="vote">添加的调查对象。</param>
		/// <returns>布尔值表示当前用户是否有添加调查的权限。</returns>
		public static bool GetInsertRight(Vote vote)
		{
			return GetInsertRight(vote, false);
		}
		#endregion



		#region GetUpdateRight
		/// <summary>
		/// 获取当前用户是否有更新调查的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="vote">更新的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新调查的权限。</returns>
		public static bool GetUpdateRight(GenericModuleDataContext dc, Vote vote, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)VoteClasses.VoteReleasePermissionCode.Update;
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(dc.VoteClasses.GetItem(vote.ClassId));
			if (!resourceId.HasValue)
				throw new ObjectNotExistsException(Res.Resources_NotExistsResource);

			bool b = dc.AccessController.GetUserIsHasPermission<Vote>(userName, vote, resourceId.Value, permissionCode);

			if (triggerException && !b)
				throw new PermissionException(userName, vote, resourceId.Value, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有更新调查的权限。
		/// </summary>
		/// <param name="vote">更新的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新调查的权限。</returns>
		public static bool GetUpdateRight(Vote vote, bool triggerException)
		{
			return GetUpdateRight(new GenericModuleDataContext(), vote, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有更新调查的权限。
		/// </summary>
		/// <param name="vote">更新的调查对象。</param>
		/// <returns>布尔值表示当前用户是否有更新调查的权限。</returns>
		public static bool GetUpdateRight(Vote vote)
		{
			return GetUpdateRight(vote, false);
		}
		#endregion



		#region GetDeleteRight
		/// <summary>
		/// 获取当前用户是否有删除调查的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="vote">删除的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除调查的权限。</returns>
		public static bool GetDeleteRight(GenericModuleDataContext dc, Vote vote, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)VoteClasses.VoteReleasePermissionCode.Delete;
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(dc.VoteClasses.GetItem(vote.ClassId));
			if (!resourceId.HasValue)
				throw new ObjectNotExistsException(Res.Resources_NotExistsResource);

			bool b = dc.AccessController.GetUserIsHasPermission<Vote>(userName, vote, resourceId.Value, permissionCode);

			if (triggerException && !b)
				throw new PermissionException(userName, vote, resourceId.Value, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有删除调查的权限。
		/// </summary>
		/// <param name="vote">删除的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除调查的权限。</returns>
		public static bool GetDeleteRight(Vote vote, bool triggerException)
		{
			return GetDeleteRight(new GenericModuleDataContext(), vote, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除调查的权限。
		/// </summary>
		/// <param name="vote">删除的调查对象。</param>
		/// <returns>布尔值表示当前用户是否有删除调查的权限。</returns>
		public static bool GetDeleteRight(Vote vote)
		{
			return GetDeleteRight(vote, false);
		}
		#endregion



		#region GetSettingRight
		/// <summary>
		/// 获取当前用户是否有设置调查的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="vote">设置的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有设置调查的权限。</returns>
		public static bool GetSettingRight(GenericModuleDataContext dc, Vote vote, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)VoteClasses.VoteReleasePermissionCode.Setting;
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(dc.VoteClasses.GetItem(vote.ClassId));
			if (!resourceId.HasValue)
				throw new ObjectNotExistsException(Res.Resources_NotExistsResource);

			bool b = dc.AccessController.GetUserIsHasPermission<Vote>(userName, vote, resourceId.Value, permissionCode);

			if (triggerException && !b)
				throw new PermissionException(userName, vote, resourceId.Value, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有设置调查的权限。
		/// </summary>
		/// <param name="vote">设置的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有设置调查的权限。</returns>
		public static bool GetSettingRight(Vote vote, bool triggerException)
		{
			return GetSettingRight(new GenericModuleDataContext(), vote, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有设置调查的权限。
		/// </summary>
		/// <param name="vote">设置的调查对象。</param>
		/// <returns>布尔值表示当前用户是否有设置调查的权限。</returns>
		public static bool GetSettingRight(Vote vote)
		{
			return GetSettingRight(vote, false);
		}



		public static bool GetSetEffectiveStateRight(GenericModuleDataContext dc, Vote vote, bool triggerException)
		{
			return GetSettingRight(dc, vote, triggerException);
		}

		public static bool GetSetEffectiveStateRight(Vote vote, bool triggerException)
		{
			return GetSetEffectiveStateRight(new GenericModuleDataContext(), vote, triggerException);
		}

		public static bool GetSetEffectiveStateRight(Vote vote)
		{
			return GetSetEffectiveStateRight(vote, false);
		}
		#endregion



		#region GetVoteRight
		/// <summary>
		/// 获取当前用户是否有参与调查的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="vote">参与的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有参与调查的权限。</returns>
		public static bool GetVoteRight(GenericModuleDataContext dc, Vote vote, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)VoteClasses.VoteReleasePermissionCode.Vote;
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(dc.VoteClasses.GetItem(vote.ClassId));
			if (!resourceId.HasValue)
				throw new ObjectNotExistsException(Res.Resources_NotExistsResource);

			bool b = dc.AccessController.GetUserIsHasPermission<Vote>(userName, vote, resourceId.Value, permissionCode);

			// 增加验证
			b = b || vote.IsAnonymous;

			if (triggerException && !b)
				throw new PermissionException(userName, vote, resourceId.Value, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有参与调查的权限。
		/// </summary>
		/// <param name="vote">参与的调查对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有参与调查的权限。</returns>
		public static bool GetVoteRight(Vote vote, bool triggerException)
		{
			return GetVoteRight(new GenericModuleDataContext(), vote, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有参与调查的权限。
		/// </summary>
		/// <param name="vote">参与的调查对象。</param>
		/// <returns>布尔值表示当前用户是否有参与调查的权限。</returns>
		public static bool GetVoteRight(Vote vote)
		{
			return GetVoteRight(vote, false);
		}
		#endregion
	}




	/// <summary>
	/// Votes 类后台管理部分。
	/// </summary>
	public static partial class Votes
	{
		public static bool GetManageListRight()
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasCategoryPermission<object>(Users.CurrentUserName, null, VoteClasses.VoteReleaseResourceCategoryId, (int)VoteClasses.VoteReleasePermissionCode.Update, App.Context.CurrentSiteId);
		}

		public static bool GetManageListRight(int classId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(classId);
			if (resourceId == null) return false;
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, resourceId.Value, (int)VoteClasses.VoteReleasePermissionCode.Setting, Sites.CurrentSiteId);
		}

		public static bool GetManageListRight(int classId,int? siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseResourceId(classId);
			if (resourceId == null) return false;
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, resourceId.Value, (int)VoteClasses.VoteReleasePermissionCode.Insert, siteId);
		}

		public static bool GetRootManageListRight(int siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			Guid? resourceId = dc.VoteClasses.GetVoteReleaseRootResourceId(siteId);
			if (resourceId == null) return false;
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, resourceId.Value, (int)VoteClasses.VoteReleasePermissionCode.Insert, siteId);
		}

		public struct VoteForManageList
		{
			public int VoteId { get; set; }
			public string Title { get; set; }
			public bool IsEffective { get; set; }
			public DateTime ReleaseDate { get; set; }
			public DateTime? ExpirationDate { get; set; }
			public bool IsMultiSelect { get; set; }
			public int VoteCount { get; set; }
			public bool IsHomeDisplay { get; set; }
			public string ChannelIds { get; set; }
		}

		public static PaginationInfo<List<VoteForManageList>> GetPaginationManageList(int classId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.Votes
					where p.ClassId == classId
					orderby p.Order descending, p.ReleaseDate descending
					select new VoteForManageList
					{
						VoteId = p.VoteId,
						Title = p.Title,
						IsEffective = p.IsEffective,
						IsMultiSelect = p.IsMultiSelect,
						ReleaseDate = p.ReleaseDate,
						ExpirationDate = p.ExpirationDate,
						VoteCount = p.VoteCount,
						IsHomeDisplay = p.IsHomeDisplay,
						ChannelIds = p.ChannelIds
					};

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.Title.Contains(keyword));

			PaginationInfo<List<VoteForManageList>> pageInfo = new PaginationInfo<List<VoteForManageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static PaginationInfo<List<VoteForManageList>> GetPaginationManageList(int classId,int? channelId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.Votes
					where p.ClassId == classId
					orderby p.Order descending, p.ReleaseDate descending
					select new VoteForManageList
					{
						VoteId = p.VoteId,
						Title = p.Title,
						IsEffective = p.IsEffective,
						IsMultiSelect = p.IsMultiSelect,
						ReleaseDate = p.ReleaseDate,
						ExpirationDate = p.ExpirationDate,
						VoteCount = p.VoteCount,
						IsHomeDisplay = p.IsHomeDisplay,
						ChannelIds = p.ChannelIds
					};

			if (channelId.HasValue)
			{
				string channels = Dictionaries.BuildDicCombineValues<int>(channelId.Value);
				q = q.Where(p => p.ChannelIds.Contains(channels));
			}

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.Title.Contains(keyword));

			PaginationInfo<List<VoteForManageList>> pageInfo = new PaginationInfo<List<VoteForManageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}
	}




	/// <summary>
	/// Votes 类前台显示部分。
	/// </summary>
	public static partial class Votes
	{
		/// <summary>
		/// 基础列表。
		/// </summary>
		public struct VoteForBaseList
		{
			public int VoteId { get; set; }
			public int ClassId { get; set; }
			public string Title { get; set; }
			public DateTime ReleaseDate { get; set; }
			public bool IsHomeDisplay { get; set; }
			public string ChannelIds { get; set; }
		}

		/// <summary>
		/// 获取基本列表查询。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="classId">类别标识。</param>
		/// <param name="keyword">检索的关键字。</param>
		/// <returns>基本列表查询。</returns>
		private static IQueryable<VoteForBaseList> GetBaseListQuery(GenericModuleDataContext dc, int? classId, string keyword)
		{
			IQueryable<VoteForBaseList> q;
			q = from p in dc.Votes
				where p.IsEffective == true
				orderby p.Order descending, p.ReleaseDate descending
				select new VoteForBaseList
				{
					VoteId = p.VoteId,
					ClassId = p.ClassId,
					Title = p.Title,
					ReleaseDate = p.ReleaseDate,
					IsHomeDisplay = p.IsHomeDisplay,
					ChannelIds=p.ChannelIds
				};

			if (classId.HasValue)
			{
				q = q.Where(p => p.ClassId == classId.Value);
			}

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.Title.Contains(keyword));

			return q;
		}

		/// <summary>
		/// 获取分页基本列表。
		/// </summary>
		/// <param name="classId">类别标识。</param>
		/// <param name="keyword">检索的关键字。</param>
		/// <param name="pageSize">页尺寸。</param>
		/// <param name="currentPage">当前页码。</param>
		/// <returns>分页基本列表。</returns>
		public static PaginationInfo<List<VoteForBaseList>> GetPaginationBaseList(int? classId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<VoteForBaseList> q = GetBaseListQuery(dc, classId, keyword);

			PaginationInfo<List<VoteForBaseList>> pageInfo = new PaginationInfo<List<VoteForBaseList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		/// <summary>
		/// 获取基本列表。
		/// </summary>
		/// <param name="classId">模块标识。</param>
		/// <param name="keyword">检索的关键字。</param>
		/// <param name="loadCount">读取的数量。</param>
		/// <returns>基本列表。</returns>
		public static List<VoteForBaseList> GetBaseList(int? classId, string keyword, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<VoteForBaseList> q = GetBaseListQuery(dc, classId, keyword);

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}


		private static IQueryable<VoteForBaseList> GetBaseListQuery(GenericModuleDataContext dc, int? classId,int? channelId, string keyword)
		{
			IQueryable<VoteForBaseList> q;
			q = from p in dc.Votes
				where p.IsEffective == true
				orderby p.Order descending, p.ReleaseDate descending
				select new VoteForBaseList
				{
					VoteId = p.VoteId,
					ClassId = p.ClassId,
					Title = p.Title,
					ReleaseDate = p.ReleaseDate,
					IsHomeDisplay = p.IsHomeDisplay,
					ChannelIds = p.ChannelIds
				};

			if (classId.HasValue)
			{
				q = q.Where(p => p.ClassId == classId.Value);
			}

			if (channelId.HasValue)
			{
				string channels = Dictionaries.BuildDicCombineValues<int>(channelId.Value);
				q = q.Where(p => p.ChannelIds.Contains(channels));
			}

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.Title.Contains(keyword));

			return q;
		}

		public static PaginationInfo<List<VoteForBaseList>> GetPaginationBaseList(int? classId, int? channelId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<VoteForBaseList> q = GetBaseListQuery(dc, classId,channelId, keyword);

			PaginationInfo<List<VoteForBaseList>> pageInfo = new PaginationInfo<List<VoteForBaseList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<VoteForBaseList> GetBaseList(int? classId, int? channelId, string keyword, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<VoteForBaseList> q = GetBaseListQuery(dc, classId,channelId, keyword);

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}

		/// <summary>
		/// 基础列表。
		/// </summary>
		public struct VoteForSummaryList
		{
			public int VoteId { get; set; }
			public int ClassId { get; set; }
			public string Title { get; set; }
			public string Summary { get; set; }
			public string VoteItems { get; set; }
			public DateTime ReleaseDate { get; set; }
			public bool IsHomeDisplay { get; set; }
			public string ChannelIds { get; set; }
		}

		/// <summary>
		/// 获取摘要列表查询。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="classId">类别标识。</param>
		/// <param name="keyword">检索的关键字。</param>
		/// <returns>摘要列表查询。</returns>
		private static IQueryable<VoteForSummaryList> GetSummaryListQuery(GenericModuleDataContext dc, int? classId, string keyword)
		{
			IQueryable<VoteForSummaryList> q;
			q = from p in dc.Votes
				where p.IsEffective == true
				orderby p.Order descending, p.ReleaseDate descending
				select new VoteForSummaryList
				{
					VoteId = p.VoteId,
					ClassId = p.ClassId,
					Title = p.Title,
					Summary = p.Summary,
					VoteItems = p.VoteItems,
					ReleaseDate = p.ReleaseDate,
					IsHomeDisplay = p.IsHomeDisplay,
					ChannelIds = p.ChannelIds
				};

			if (classId.HasValue)
			{
				q = q.Where(p => p.ClassId == classId.Value);
			}

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.Title.Contains(keyword));

			return q;
		}

		/// <summary>
		/// 获取分页摘要列表。
		/// </summary>
		/// <param name="classId">类别标识。</param>
		/// <param name="keyword">检索的关键字。</param>
		/// <param name="pageSize">页尺寸。</param>
		/// <param name="currentPage">当前页码。</param>
		/// <returns>分页摘要列表。</returns>
		public static PaginationInfo<List<VoteForSummaryList>> GetPaginationSummaryList(int? classId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<VoteForSummaryList> q = GetSummaryListQuery(dc, classId, keyword);

			PaginationInfo<List<VoteForSummaryList>> pageInfo = new PaginationInfo<List<VoteForSummaryList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		/// <summary>
		/// 获取摘要列表。
		/// </summary>
		/// <param name="classId">模块标识。</param>
		/// <param name="keyword">检索的关键字。</param>
		/// <param name="loadCount">读取的数量。</param>
		/// <returns>摘要列表。</returns>
		public static List<VoteForSummaryList> GetSummaryList(int? classId, string keyword, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<VoteForSummaryList> q = GetSummaryListQuery(dc, classId, keyword);

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}

		private static IQueryable<VoteForSummaryList> GetSummaryListQuery(GenericModuleDataContext dc, int? classId, int? channelId, string keyword)
		{
			IQueryable<VoteForSummaryList> q;
			q = from p in dc.Votes
				where p.IsEffective == true
				orderby p.Order descending, p.ReleaseDate descending
				select new VoteForSummaryList
				{
					VoteId = p.VoteId,
					ClassId = p.ClassId,
					Title = p.Title,
					Summary = p.Summary,
					VoteItems = p.VoteItems,
					ReleaseDate = p.ReleaseDate,
					IsHomeDisplay = p.IsHomeDisplay,
					ChannelIds = p.ChannelIds
				};

			if (classId.HasValue)
			{
				q = q.Where(p => p.ClassId == classId.Value);
			}

			if (channelId.HasValue)
			{
				string channels = Dictionaries.BuildDicCombineValues<int>(channelId.Value);
				q = q.Where(p => p.ChannelIds.Contains(channels));
			}

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.Title.Contains(keyword));

			return q;
		}
		public static PaginationInfo<List<VoteForSummaryList>> GetPaginationSummaryList(int? classId, int? channelId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<VoteForSummaryList> q = GetSummaryListQuery(dc, classId,channelId, keyword);

			PaginationInfo<List<VoteForSummaryList>> pageInfo = new PaginationInfo<List<VoteForSummaryList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}
		public static List<VoteForSummaryList> GetSummaryList(int? classId, int? channelId, string keyword, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<VoteForSummaryList> q = GetSummaryListQuery(dc, classId,channelId, keyword);

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}


	}
}